package cn.hdu.liang.ch06;

import java.util.List;
import java.util.concurrent.*;

import static cn.hdu.liang.ch05.LaunderThrowable.launderThrowable;

/**
 * 使用CompletionService，使页面元素在下载完成后立即显示出来
 */
public abstract class Renderer {
    private final ExecutorService executor;

    Renderer(ExecutorService executor) {
        this.executor = executor;
    }

    void renderPage(CharSequence source) {

        final List<ImageInfo> info = scanForImageInfo(source);
        CompletionService<ImageData> completionService = new ExecutorCompletionService<>(executor);

        for(final ImageInfo imageInfo : info) {
            completionService.submit(imageInfo::downloadImage);
        }
        renderText(source);

        try {
            for(int t = 0, n = info.size(); t < n; t++) {
                Future<ImageData> f = completionService.take();
                ImageData imageData = f.get();
                renderImage(imageData);
            }
        } catch(InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch(ExecutionException e) {
            throw launderThrowable(e.getCause());
        }
    }

    interface ImageData {
    }

    interface ImageInfo {
        ImageData downloadImage();
    }

    abstract void renderText(CharSequence s);

    abstract List<ImageInfo> scanForImageInfo(CharSequence s);

    abstract void renderImage(ImageData i);

}
